#include "AppointmentDairy.h"

AppointmentDairy::AppointmentDairy() {

	for (int i = 0; i < Day::days_in_week; i++)
		days_.push_back(Day(i));
}

AppointmentDairy::AppointmentDairy(const AppointmentDairy & diary) {
	this->days_ = diary.getDays();
}

AppointmentDairy & AppointmentDairy::operator= (const AppointmentDairy & diary) {
	if (this != &diary) {
		this->days_ = diary.getDays();
	}

	return *this;
}

void AppointmentDairy::addAppointment(const int & day_index, const int & start_hour, const int & start_min,
										const int & end_hour, const int & end_min, const string & subject) {
	
	if ((day_index < 0) || (day_index > 6))
		throw WrongDayException();

	if (end_hour < start_hour)
		throw WrongMeetingHoursException();

	if ((end_hour == start_hour) && (end_min <= start_min))
		throw WrongMeetingHoursException();

	if ((start_hour < 0) || (start_hour >= 24) || (end_hour < 0) || (end_hour >= 24) ||			// => hour is out of bounds (00 - 23)
	    (start_min  < 0) || (start_min  >= 60) || (end_min  < 0) || (end_min  >= 60))					// => minutes are out of bounds (00 - 59)
			throw InvalidTimeException();

	Appointment * app = new Appointment(start_hour, start_min, end_hour, end_min, subject, day_index);

	if (intersects(*app))
	{
		delete app;
		throw IntersectingAppointmentsException();
	}
	days_[day_index].addAppointment(*app);

	delete(app);
}

void AppointmentDairy::removeAppointment(const Appointment & app) {
	days_[app.getDayIndex()].removeAppointment(app);
}

const Appointment * AppointmentDairy::find(const int & day_index, const int & start_hour, const int & start_min) const {
	return days_[day_index].find(start_hour, start_min);
}

void AppointmentDairy::copyAppointment(const Appointment & app, const int & day_index, const int & start_hour, const int & start_min) {

	int diff = (app.getEndHour() * 60 + app.getEndMin()) - (app.getStartHour() * 60 + app.getStartMin());
	int end_new = start_hour*60 + start_min + diff;
	int end_hour = end_new / 60;

	if (end_hour >= 24)
		throw IllegalCopyException();

	int end_min = end_new % 60;

	try {
		addAppointment(day_index, start_hour, start_min, end_hour, end_min, app.getSubject());
	} catch (const ADException & ex) {
		throw;
	}
}

bool AppointmentDairy::intersects (const Appointment & app) {
	
	const int & day_index = app.getDayIndex();
	 set<Appointment>::const_iterator it = \
		 std::find(days_[day_index].getAppointments().begin(), days_[day_index].getAppointments().end(), app);
	 
	 return (it != days_[day_index].getAppointments().end());

}

ostream &operator<< (ostream& os, const AppointmentDairy& AD) {
	
	for (int i = 0; i < Day::days_in_week; i++) {
		os << AD.days_[i];
	}

	return os;
}